package com.bstek.bdf2.core.security.service;


import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.model.DefaultUser;
import com.bstek.bdf2.core.model.Role;
import com.bstek.bdf2.core.security.SecurityInterceptorAdapter;
import com.bstek.bdf2.core.service.IGroupService;
import com.bstek.bdf2.core.service.IRoleService;
import com.bstek.bdf2.core.service.IUserService;
import com.bstek.bdf4.constant.Constants;
import com.bstek.bdf4.rest.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.context.HttpRequestResponseHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;

/**
 *  自定义权限实现
 *
 */
@Service("ss")
public class PermissionService {
    private static final Logger log = LoggerFactory.getLogger(PermissionService.class);


    @Resource
    private IGroupService groupService;

    @Resource
    private IUserService userService;

    @Resource
    private IRoleService roleService;

    @Resource
    private JwtTokenService jwtTokenService;

    @Resource
    private HttpServletRequest request;


    /**
     * 权限标识分隔符
     */
    public static final String PERMISSION_DELIMETER = ",";


    /**
     * 验证用户是否具备某权限
     *
     * @param permission 权限字符串
     * @return 用户是否具备某权限
     */
    public boolean hasPermi(String permission) {
        if (StringUtils.isEmpty(permission)) {
            return false;
        }
        IUser user = ContextHolder.getLoginUser();
        if (user == null) {
            //TODO 去token里面获取用户信息

            DefaultUser defaultUser = createUser();
            if (defaultUser.isAdministrator()) {
                return true;
            }
            Set<String> permissions = groupService.loadPermissions(defaultUser.getUsername());
            return buildPermissions(permissions, permission);
        }
        //是系统管理员直接授权
        if (user.isAdministrator()) {
            return true;
        }
        Set<String> permissions = user.getPermissions();
        return buildPermissions(permissions, permission);
    }

    private DefaultUser createUser() {
        String token = jwtTokenService.getToken(request);
        if (StringUtils.isEmpty(token)) {
            throw new AccessDeniedException("在请求头没有获取到token信息！");
        }
        String username = jwtTokenService.parseToken(token);
        if (StringUtils.isEmpty(username)) {
            throw new AccessDeniedException("在token里获取到用户信息为空！");

        }
        DefaultUser defaultUser = (DefaultUser) userService.loadUserByUsername(username);
        if (defaultUser == null) {
            throw new AccessDeniedException("根据用户名:" + username + ",获取到的信息为空!");
        }
        return defaultUser;
    }

    private boolean buildPermissions(Set<String> permissions, String permission) {
        if (CollectionUtils.isEmpty(permissions)) {
            log.error("用户获取到的权限信息为空!");
            return false;
        }
        return hasPermissions(permissions, permission);
    }


    /**
     * 验证用户是否不具备某权限，与 hasPermi逻辑相反
     *
     * @param permission 权限字符串
     * @return 用户是否不具备某权限
     */
    public boolean lacksPermi(String permission) {
        return hasPermi(permission) != true;
    }

    /**
     * 判断用户是否拥有某个角色
     *
     * @param role 角色字符串
     * @return 用户是否具备某角色
     */
    public boolean hasRole(String role) {
        if (StringUtils.isEmpty(role)) {
            return false;
        }
        IUser loginUser = ContextHolder.getLoginUser();
        List<Role> roles = null;
        if (loginUser == null) {
            DefaultUser defaultUser = createUser();
            if (defaultUser.isAdministrator()) {
                return true;
            }
            roles = roleService.loadUserRoles(defaultUser.getUsername());
        } else {
            if (loginUser.isAdministrator()) {
                return true;
            }
            roles = loginUser.getRoles();
        }
        return buildHasRole(roles, role);

    }

    private boolean buildHasRole(List<Role> roles, String role) {
        if (CollectionUtils.isEmpty(roles)) {
            return false;
        }
        for (Role sysRole : roles) {
            String roleKey = sysRole.getName();
            if (roleKey.equals(trim(role))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 验证用户是否不具备某角色，与 isRole逻辑相反。
     *
     * @param role 角色名称
     * @return 用户是否不具备某角色
     */
    public boolean lacksRole(String role) {
        return hasRole(role) != true;
    }

    /**
     * 验证用户是否具有以下任意一个权限
     *
     * @param permissions 以 PERMISSION_DELIMETER 为分隔符的权限列表
     * @return 用户是否具有以下任意一个权限
     */
    public boolean hasAnyPermi(String permissions) {
        if (StringUtils.isEmpty(permissions)) {
            return false;
        }
        for (String permission : permissions.split(PERMISSION_DELIMETER)) {
            if (permission != null && hasPermi(permission)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 验证用户是否具有以下任意一个角色
     *
     * @param roles 以 ROLE_NAMES_DELIMETER 为分隔符的角色列表
     * @return 用户是否具有以下任意一个角色
     */
    public boolean hasAnyRoles(String roles) {
        if (StringUtils.isEmpty(roles)) {
            return false;
        }
        for (String roleKey : roles.split(Constants.ROLE_DELIMETER)) {
            if (hasRole(roleKey)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否包含权限
     *
     * @param permissions 权限列表
     * @param permission  权限字符串
     * @return 用户是否具备某权限
     */
    private boolean hasPermissions(Set<String> permissions, String permission) {
        return permissions.contains(Constants.ALL_PERMISSION) || permissions.contains(trim(permission));
    }

    /**
     * 去空格
     */
    public static String trim(String str) {
        return (str == null ? "" : str.trim());
    }
}
